#ifndef __SINGLETON_INCLUDED
#define __SINGLETON_INCLUDED


namespace Audio
{	
	struct NoLock
	{
		static void Lock(){ }
		static void Unlock(){}	
	};	

	template<typename T>
	struct DefaultCreateDestroyProxy
	{
		static T* Create()
		{
			return new T();
		}
		static void Destroy(T* t)
		{
			delete t;
			t = NULL;
		}
	};

	template<typename T, typename M = NoLock, typename C = DefaultCreateDestroyProxy<T> >
	class Singleton
	{
	public:
		typedef T ClientType;
		typedef M MultiThreadProxy;
		typedef C CreateDestroyProxy;

		static T* Get()
		{
			if(instance == NULL)
			{
				MultiThreadProxy::Lock();
				if(instance == NULL)
				{
					try
					{
						instance = CreateDestroyProxy::Create(); 
					}					
					catch (...)
					{
						instance = NULL;
					}					
				}
				MultiThreadProxy::Unlock();				
			}
			return instance;
		}

		static void DestroyInstance()
		{
			MultiThreadProxy::Lock();
			CreateDestroyProxy::Destroy(instance);
			MultiThreadProxy::Unlock();	
		}
	protected:
		Singleton(){};
	private:
		Singleton(const Singleton& other);
		Singleton& operator= (const Singleton& other);

		static T* instance;

	};

	template<typename T, typename M, typename C>
	T* Singleton<T,M,C>::instance = NULL;
}


#endif  __SINGLETON_INCLUDED